package com.xingda.packing.dmss.config;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xingda.packing.dmss.config.appset.AppSetParam;
import com.xingda.packing.dmss.config.appset.AppSetUrl;
import com.xingda.packing.dmss.domain.PackProductionLine;
import com.xingda.packing.dmss.enums.AlarmTriggerType;
import com.xingda.packing.dmss.events.EventCreater;
import com.xingda.packing.dmss.minitor.entity.*;
import com.xingda.packing.dmss.minitor.mapper.*;
import com.xingda.packing.dmss.minitor.service.IPkDownWheelService;
import com.xingda.packing.dmss.plc.entity.PlcItem;
import com.xingda.packing.dmss.plc.service.PlcDirectiveService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.*;

/**
 * 增加定时任务开关
 */
@Configuration
//启用定时任务
@EnableScheduling
//配置文件读取是否启用此配置
@ConditionalOnProperty(prefix = "scheduling", name = "enabled", havingValue = "true")
public class SchedulingConfig {
    @Resource
    IPkDownWheelService pkDownWheelService;
    @Resource
    private PackProductionLine packProductionLine;
    @Resource
    private PlcDirectiveService plcDirectiveService;
    @Resource
    private PkActionMapper pkActionMapper;
    @Resource
    EventCreater eventCreater;
    @Resource
    PkPlcAlarmMapper pkPlcAlarmMapper;
    @Resource
    PkAlarmTypeMapper pkAlarmTypeMapper;
    @Resource
    PkEventsMapper pkEventsMapper;
    @Resource
    PkAgvTaskMapper pkAgvTaskMapper;

    /**
     * 删除n分钟之前的卸轮记录
     */
    @Scheduled(cron = "0 0/5 * * * ? ")
    @Async
    public void removeDownWheel() {
        if (packProductionLine.getEnv().startsWith("xd-prod")) {
            pkDownWheelService.removeMinuteAgo();
            if (AppSetParam.auto_reomve_packing_downwheel) {
                pkDownWheelService.removePacking();
            }
        }
    }

    @Scheduled(cron = "0/1 * * * * ? ")
    @Async
    public void monitorPlcStatus() {
        if (packProductionLine.getEnv().startsWith("xd-prod")) {
            if (plcDirectiveService.getPlcStatus()) {
                plcDirectiveService.writePlcStatus();
            }
        }
    }

    @Scheduled(cron = "0 0/1 * * * ? ")
    @Async
    public void getDownWheel() {
        if (packProductionLine.getEnv().startsWith("xd-prod")) {
            HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("area", packProductionLine.getArea());
            String s = HttpUtil.get(AppSetUrl.down_wheel_url, paramMap);
            List<PkDownWheel> pkDownWheels = JSONArray.parseArray(s, PkDownWheel.class);
            pkDownWheelService.saveBatch(pkDownWheels);
        }
    }

    @Scheduled(cron = "0 0 0 * * ?")
    @Async
    public void deleteTask() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -7);
        LambdaQueryWrapper<PkEvents> eventsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        eventsLambdaQueryWrapper.le(PkEvents::getCreateTime, calendar.getTime()).orderByDesc(PkEvents::getCreateTime);
        pkEventsMapper.delete(eventsLambdaQueryWrapper);
    }

    @Scheduled(cron = "0/5 * * * * ? ")
    @Async
    public void monitorRobotAction() {
        boolean singleton = packProductionLine.getModel().equals("singleton");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -AppSetParam.robot_not_move_alarm_minute);
        if (singleton) {
            //只检测area1
            LambdaQueryWrapper<PkAction> pkActionQueryWrapper = Wrappers.lambdaQuery();
            pkActionQueryWrapper.ge(PkAction::getStartTime, calendar.getTime()).orderByDesc(PkAction::getStartTime);
            List<PkAction> pkAction = pkActionMapper.selectList(pkActionQueryWrapper);
            eventCreater.createTriggerAlarm(AlarmTriggerType.ROBOT_TIMEOUT_NOT_MOVE, pkAction.isEmpty(), 1);
        } else {
            //检测1
            LambdaQueryWrapper<PkAction> pkActionQueryWrapper1 = Wrappers.lambdaQuery();
            pkActionQueryWrapper1.ge(PkAction::getStartTime, calendar.getTime()).orderByDesc(PkAction::getStartTime).eq(PkAction::getArea, 1);
            List<PkAction> pkAction1 = pkActionMapper.selectList(pkActionQueryWrapper1);
            eventCreater.createTriggerAlarm(AlarmTriggerType.ROBOT_TIMEOUT_NOT_MOVE, pkAction1.isEmpty(), 1);
            //检测2
            LambdaQueryWrapper<PkAction> pkActionQueryWrapper2 = Wrappers.lambdaQuery();
            pkActionQueryWrapper2.ge(PkAction::getStartTime, calendar.getTime()).orderByDesc(PkAction::getStartTime).eq(PkAction::getArea, 2);
            List<PkAction> pkAction2 = pkActionMapper.selectList(pkActionQueryWrapper2);
            eventCreater.createTriggerAlarm(AlarmTriggerType.ROBOT_TIMEOUT_NOT_MOVE, pkAction2.isEmpty(), 2);
        }
    }

    @Scheduled(cron = "0/2 * * * * ? ")
    @Async
    public void monitorPlcAlarm() {
        if (packProductionLine.getEnv().startsWith("xd-prod")) {
            List<PlcItem> plcItemList = new ArrayList<>();
            for (PkPlcAlarm pkPlcAlarm : pkPlcAlarmMapper.selectList(null)) {
                plcItemList.add(new PlcItem(pkPlcAlarm.getContent(), pkPlcAlarm.getAddress()));
            }
            JSONObject jsonObject = plcDirectiveService.readVals(plcItemList);
            for (String next : jsonObject.keySet()) {
                LambdaQueryWrapper<PkPlcAlarm> pkPlcAlarmLambdaQueryWrapper = new LambdaQueryWrapper<>();
                pkPlcAlarmLambdaQueryWrapper.eq(PkPlcAlarm::getContent, next);
                PkPlcAlarm pkPlcAlarm = pkPlcAlarmMapper.selectOne(pkPlcAlarmLambdaQueryWrapper);
                LambdaQueryWrapper<PkAlarmType> pkAlarmTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
                pkAlarmTypeLambdaQueryWrapper.eq(PkAlarmType::getId, pkPlcAlarm.getId());
                eventCreater.createTriggerAlarm(pkAlarmTypeMapper.selectOne(pkAlarmTypeLambdaQueryWrapper), jsonObject.getBooleanValue(next), pkPlcAlarm.getArea());
            }
        }
    }

    @Scheduled(cron = "0/1 * * * * ? ")
    @Async
    public void monitorAgv() {
        if (packProductionLine.getEnv().startsWith("xd-prod")) {
            LambdaQueryWrapper<PkAgvTask> pkAgvTaskLambdaQueryWrapper = new LambdaQueryWrapper<>();
            pkAgvTaskLambdaQueryWrapper.isNull(PkAgvTask::getFinishTime);
            PkAgvTask pkAgvTask = pkAgvTaskMapper.selectOne(pkAgvTaskLambdaQueryWrapper);
            if (Objects.nonNull(pkAgvTask)) {
                LambdaQueryWrapper<PkAction> pkActionLambdaQueryWrapper = new LambdaQueryWrapper<>();
                pkActionLambdaQueryWrapper.isNull(PkAction::getFinishTime);
                List<PkAction> pkActions = pkActionMapper.selectList(pkActionLambdaQueryWrapper);
                if (pkAgvTask.getType() == 1) {
                    //取满托
                    packProductionLine.setAllowPass(plcDirectiveService.allowTask1() && pkActions.isEmpty() && packProductionLine.isAgvComing());
                } else {
                    //放空拖
                    packProductionLine.setAllowPass(plcDirectiveService.allowTask2() && pkActions.isEmpty() && packProductionLine.isAgvComing());
                }
            } else {
                packProductionLine.setAllowPass(plcDirectiveService.allowTask1() || plcDirectiveService.allowTask2());
            }
        }
    }
}
